#ifndef PSFSteppingAction_h
#define PSFSteppingAction_h 1

#include "G4Types.hh"
#include "G4UserSteppingAction.hh"

class PSFDetectorConstruction;
class PSFSteppingActionMessenger;
class PSFEventAction;

class G4OpBoundaryProcess;
class G4Track;
class G4StepPoint;

class PSFSteppingAction : public G4UserSteppingAction
{
public:
  PSFSteppingAction(PSFDetectorConstruction *, PSFEventAction *);
  ~PSFSteppingAction() override;

  void UserSteppingAction(const G4Step *) override;

  // Set the bounce limit, 0 for no limit
  void SetBounceLimit(G4int);

  G4int GetNumberOfBounces();
  G4int GetNumberOfClad1Bounces();
  G4int GetNumberOfClad2Bounces();
  G4int GetNumberOfPSFCoreBounces();
  // return number of successful events and reset the counter
  G4int ResetSuccessCounter();

private:
  // Artificially kill the photon after it has bounced more than this number
  G4int fBounceLimit = 100000;
  // number of photons that reach the end
  G4int fCounterEnd = 0;
  // number of photons that didn't make it to the end
  G4int fCounterMid = 0;
  // total number of bounces that a photon been through
  G4int fCounterBounce = 0;
  // number of bounces that a photon been through within the fibre
  G4int fCounterPSFCoreBounce = 0;
  // number of bounces that a photon been through from Cladding 1 to 2
  G4int fCounterClad1Bounce = 0;
  // number of bounces that a photon been through from Cladding 2 to World
  G4int fCounterClad2Bounce = 0;

  // initial gamma of the photon
  G4double fInitGamma = -1.;
  // initial theta of the photon
  G4double fInitTheta = -1.;
  G4OpBoundaryProcess *fOpProcess = nullptr;

  PSFDetectorConstruction *fDetector = nullptr;
  PSFSteppingActionMessenger *fSteppingMessenger = nullptr;
  PSFEventAction *fEventAction = nullptr;

  inline void ResetCounters()
  {
    fCounterBounce = 0;
    fCounterPSFCoreBounce = 0;
    fCounterClad1Bounce = 0;
    fCounterClad2Bounce = 0;
    fInitGamma = -1;
    fInitTheta = -1;
  }
};

#endif
